package com.terrapages.wmsc4j.layer;

import org.apache.log4j.Logger;

import com.terrapages.wmsc4j.bean.BBox;
import com.terrapages.wmsc4j.bean.Pos;
import com.terrapages.wmsc4j.cache.Cache;
import com.terrapages.wmsc4j.layer.resolution.ResolutionSet;
import com.terrapages.wmsc4j.layer.tile.Tile;
import com.terrapages.wmsc4j.layer.tile.TileFormat;
import com.terrapages.wmsc4j.wms.WMSService;

/**
 * This type of layer extends {@link AbstractLayer}.
 * When a tile is requested from this layer and was not found in cache,
 * the layer uses a WMS service to get the image and populate the cache for the next time.
 * 
 * @author mvivian
 */
public abstract class AbstractLiveLayer extends AbstractLayer 
{
	protected WMSService wmsService;
	
	private static Logger log = Logger.getLogger(AbstractLiveLayer.class);
	
	
	/**
	 * Copies a existing AbstractLiveLayer using a new set of resolutions and a new coverage.
	 * @param layer existing AbstractLiveLayer
	 * @param resolutions new set of resolutions
	 * @param coverage new coverage area.
	 */
	protected AbstractLiveLayer(AbstractLiveLayer layer, ResolutionSet resolutions, BBox coverage) {
		super(layer, resolutions, coverage);
		wmsService = layer.wmsService;
	}

	/**
	 * Contructs AbstractLiveLayer 
	 * @param wmsService
	 * @param cache
	 * @param resolutions
	 * @param tilesize
	 * @param coverage
	 * @param origin
	 * @param title
	 */
	public AbstractLiveLayer(WMSService wmsService, Cache cache, ResolutionSet resolutions, TileFormat format, BBox coverage, Pos origin, String title) {
		super(cache, resolutions, format, coverage, origin, title);
		this.wmsService = wmsService;
	}
	
	/**
	 * Method that is called when requested image was not in cache. 
	 * The image is requested from a WMS Service and then the putInCacheAction(tile) is called.
	 * @param tile
	 */
	protected void notInCacheAction(final Tile tile)
	{
		log.debug("Tile " + tile.toString() + " not in cache, requesting from wms");
		tile.setImage(wmsService.getImage(tile.getBoundingBox(), tile.getTileSize()));
		putInCacheAction(tile);
	}
	
	/**
	 * Method is called to put the new Image into cache because it was originally not found in cache.
	 * @param tile
	 */
	protected abstract void putInCacheAction(final Tile tile);
}
